import java.util.*;

/**
 * @author deity
 * @version 1.0
 * @date 2020/11/8 22:50
 * <p>
 * Lambda 性能测试
 */
public class LambdaPerformanceTest {

    public static void main(String[] args) {

        Random random = new Random();
        /**
         * 1-基本数据类型: 整数
         */
        List<Integer> integerList = new ArrayList<>();
        for (int i = 0; i < 1000000; i++) {
            integerList.add(random.nextInt(Integer.MAX_VALUE));
        }

        // 1-1 stream
        testStream(integerList);
        // 1-2 parallelStream
        testPrallelStream(integerList);
        // 1-3 普通for
        testForLoop(integerList);
        // 1-4 增强for
        testStrongForloop(integerList);
        // 1-5 迭代器
        testIterator(integerList);

        System.out.println("---------------------------------------------------------------------------------------------");
        /**
         * 2-复杂数据类型: 对象
         */
        List<Product> productList = new ArrayList<>();
        for (int i = 0; i < 1000000; i++) {
            productList.add(new Product("pro" + i, i, random.nextInt(Integer.MAX_VALUE)));
        }
        testProductStream(productList);
        testProductPrallelStream(productList);
        testProductForLoop(productList);
        testProductStrongForloop(productList);
        testProductIterator(productList);


    }

    /**
     * ##############################################
     * 普通数据 -------------start-----------
     * ##############################################
     */
    public static void testStream(List<Integer> list) {
        long start = System.currentTimeMillis();
        Optional optional = list.stream().max(Integer::compareTo);
        System.out.println(optional.get());

        long end = System.currentTimeMillis();
        System.out.println("普通数据-->testStream:" + (end - start));
    }

    public static void testPrallelStream(List<Integer> list) {
        long start = System.currentTimeMillis();
        Optional optional = list.parallelStream().max(Integer::compareTo);
        System.out.println(optional.get());

        long end = System.currentTimeMillis();
        System.out.println("普通数据-->testPrallelStream:" + (end - start));
    }

    public static void testForLoop(List<Integer> list) {
        long start = System.currentTimeMillis();

        int max = Integer.MIN_VALUE;
        for (int i = 0; i < list.size(); i++) {
            int current = list.get(i);
            if (current > max) {
                max = current;
            }
        }
        System.out.println(max);

        long end = System.currentTimeMillis();
        System.out.println("普通数据-->testForLoop:" + (end - start));
    }

    public static void testStrongForloop(List<Integer> list) {
        long start = System.currentTimeMillis();

        int max = Integer.MIN_VALUE;
        for (Integer integer : list) {
            if (integer > max) {
                max = integer;
            }
        }
        System.out.println(max);
        long end = System.currentTimeMillis();
        System.out.println("普通数据-->testStrongForloop:" + (end - start));
    }

    public static void testIterator(List<Integer> list) {
        long start = System.currentTimeMillis();

        Iterator<Integer> it = list.iterator();
        int max = it.next();
        while (it.hasNext()) {
            int current = it.next();
            if (current > max) {
                max = current;
            }
        }
        System.out.println(max);

        long end = System.currentTimeMillis();
        System.out.println("普通数据-->testIterator:" + (end - start));
    }

    /**
     * ##############################################
     * end -------------start-----------
     * ##############################################
     */

    public static void testProductStream(List<Product> list) {
        long start = System.currentTimeMillis();
        Optional optional = list.stream().max((p1, p2) -> p1.hot - p2.hot);
        System.out.println(optional.get());

        long end = System.currentTimeMillis();
        System.out.println("对象-->testProductStream:" + (end - start));
    }

    public static void testProductPrallelStream(List<Product> list) {
        long start = System.currentTimeMillis();
        Optional optional = list.parallelStream().max((p1, p2) -> p1.hot - p2.hot);
        System.out.println(optional.get());

        long end = System.currentTimeMillis();
        System.out.println("对象-->testProductPrallelStream:" + (end - start));
    }

    public static void testProductForLoop(List<Product> list) {
        long start = System.currentTimeMillis();
        Product maxHot = list.get(0);
        for (int i = 0; i < list.size(); i++) {
            Product current = list.get(i);
            if (current.hot > maxHot.hot) {
                maxHot = current;
            }
        }
        System.out.println(maxHot);
        long end = System.currentTimeMillis();
        System.out.println("对象-->testProductForLoop:" + (end - start));
    }

    public static void testProductStrongForloop(List<Product> list) {
        long start = System.currentTimeMillis();

        Product maxHot = list.get(0);
        for (Product product : list) {
            if (product.hot > maxHot.hot) {
                maxHot = product;
            }
        }
        System.out.println(maxHot);
        long end = System.currentTimeMillis();
        System.out.println("对象-->testProductStrongForloop:" + (end - start));
    }

    public static void testProductIterator(List<Product> list) {
        long start = System.currentTimeMillis();

        Iterator<Product> it = list.iterator();
        Product maxHot = it.next();
        while (it.hasNext()) {
            Product current = it.next();
            if (current.hot > maxHot.hot) {
                maxHot = current;
            }
        }
        System.out.println(maxHot);
        long end = System.currentTimeMillis();
        System.out.println("对象-->testProductIterator:" + (end - start));
    }

}

class Product {
    String name;//名称
    Integer stock;//库存
    Integer hot;//热度

    public Product(String name, Integer stock, Integer hot) {
        this.name = name;
        this.stock = stock;
        this.hot = hot;
    }
}